import Geom from '../geom'

const DouglasPeucker = {}

// @dest array to contain point removal thresholds
// @xx, @yy arrays of x, y coords of a path
// @zz (optional) array of z coords for spherical simplification
//
DouglasPeucker.calcArcData = function(dest, xx, yy, zz) {
  const len = dest.length
  const useZ = !!zz

  dest[0] = dest[len-1] = Infinity
  if (len > 2) {
    procSegment(0, len-1, 1, Number.MAX_VALUE)
  }

  function procSegment(startIdx, endIdx, depth, distSqPrev) {
    // get endpoint coords
    const ax = xx[startIdx]
    const ay = yy[startIdx]
    const cx = xx[endIdx]
    const cy = yy[endIdx]
    let az = null
    let cz = null
    if (useZ) {
      az = zz[startIdx]
      cz = zz[endIdx]
    }

    let maxDistSq = 0
    let maxIdx = 0
    let distSqLeft = 0
    let distSqRight = 0
    let distSq = null

    for (let i=startIdx+1; i<endIdx; i++) {
      if (useZ) {
        distSq = Geom.pointSegDistSq3D(xx[i], yy[i], zz[i], ax, ay, az, cx, cy, cz)
      } else {
        distSq = Geom.pointSegDistSq(xx[i], yy[i], ax, ay, cx, cy)
      }

      if (distSq >= maxDistSq) {
        maxDistSq = distSq
        maxIdx = i
      }
    }

    // Case -- threshold of parent segment is less than threshold of curr segment
    // Curr max point is assigned parent's threshold, so parent is not removed
    // before child as simplification is increased.
    //
    if (distSqPrev < maxDistSq) {
      maxDistSq = distSqPrev
    }

    if (maxIdx - startIdx > 1) {
      distSqLeft = procSegment(startIdx, maxIdx, depth+1, maxDistSq)
    }
    if (endIdx - maxIdx > 1) {
      distSqRight = procSegment(maxIdx, endIdx, depth+1, maxDistSq)
    }

    // Case -- max point of curr segment is highest-threshold point of an island polygon
    // Give point the same threshold as the next-highest point, to prevent
    // a 3-vertex degenerate ring.
    if (depth == 1 && ax == cx && ay == cy) {
      maxDistSq = Math.max(distSqLeft, distSqRight)
    }

    dest[maxIdx] =  Math.sqrt(maxDistSq)
    return maxDistSq
  }
}
export default DouglasPeucker
